from PyQt5 import QtCore
from PyQt5.QtCore import pyqtSignal
from PyQt5.QtGui import QImage, QPixmap
from PyQt5.Qt import *
from PyQt5.Qt import QThread
import cv2 
import pyzbar.pyzbar as pyzbar
import json
import time
import os
import numpy as np
import logging
import multiprocessing
import server_
from PIL import Image

logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)

kernel_2 = np.ones((2, 2), np.uint8)  # 2x2的卷积核
kernel_3 = np.ones((3, 3), np.uint8)  # 3x3的卷积核
kernel_4 = np.ones((4, 4), np.uint8)  # 4x4的卷积核
kernel_8 = np.ones((8, 8), np.uint8)

draw_color = (0,255,0)

Lower_red = np.array([0, 61, 136])    #red
Upper_red = np.array([5, 255, 255])
draw_red = draw_color
red = [Lower_red, Upper_red, 'red',draw_red]

Lower_green = np.array([39, 60, 133])
Upper_green = np.array([96, 255, 255])
draw_green =draw_color
green = [Lower_green, Upper_green, 'green',draw_green]

Lower_blue = np.array([67, 91, 170])
Upper_blue = np.array([113, 193, 255])
draw_blue =draw_color
blue = [Lower_blue, Upper_blue, 'blue',draw_blue]

Lower_yellow = np.array([21, 103, 63])   
Upper_yellow = np.array([37, 255, 255])
draw_yellow = draw_color
yellow = [Lower_yellow, Upper_yellow, 'yellow',draw_yellow]

color_list = [red,blue,green,yellow]
plate_list = {1,2,3,4}
camera_nun = 9
x1 = 580
x2 = 1040
y1 = 243
y2 = 700

class Camera_Thread(QThread):

    cap_signal = pyqtSignal(str)

    def __init__(self,label,gui_signal):
        super().__init__()
        self.stop = False
        self.Is_exit = False
        self.cap= None
        self.frame = None
        self.label = label

        self.gui_signal=gui_signal
        self.cap_signal.connect(self.cap_camera)

        self.count_pos = 0
        self.plate_position = {1: 'empty', 2: 'empty', 3: 'empty', 4:'empty'} 
        
        self.master =server_.Server_Tcp(self.gui_signal)
        self.master.start()
        self.program_flag = 6

    def exit(self):
        self.stop = True
        self.Is_exit= True
    
    #### APP 
    def ocr_test(self,img):
        try:
            pass

        except Exception as e:
            logger.error(e,exc_info=True)

    #### 二维码识别
    def QR_test(self,img):
        try:
            # 使用pyzbar解析二维码图片内容
            barcodes = pyzbar.decode(img)
            if barcodes:
                for barcode in barcodes:

                    # 提取条形码的边界框的位置
                    # 画出图像中条形码的边界框
                    (x, y, w, h) = barcode.rect
                    cv2.rectangle(self.frame, (x, y), (x + w, y + h), (0, 255, 255), 3)
            
                    # 条形码数据为字节对象，所以如果我们想在输出图像上画出来，就需要先将它转换成字符串  类型也直接识别出来了
                    barcodeData = barcode.data.decode("utf-8")
                    print(f'barcodeData is {barcodeData}')
                    barcodeType = barcode.type
                    self.QR_value = int(barcodeData)

                    center_x = int(x+w/2)
                    center_y = int(y+h/2)
                    feature = [center_x,center_y,0]

                    if abs(x2 - center_x) < 30 and  abs( y1 - feature[1]) < 30:
                        for i in range(1,5):
                            if i == self.QR_value:
                                self.master.robot.robot_getQR(1)
                                self.master.robot.robot_PutQR(i)                                
                        self.plate_position[1] = self.QR_value
                    elif abs(x2 - center_x) < 30 and  abs( y2 - feature[1]) < 30:
                        for i in range(1,5):
                            if i == self.QR_value:
                                self.master.robot.robot_getQR(2)
                                self.master.robot.robot_PutQR(i)  
                    elif abs(x1 - center_x) < 30 and  abs( y1 - feature[1]) < 30:
                        for i in range(1,5):
                            if i == self.QR_value:
                                self.master.robot.robot_getQR(3)
                                self.master.robot.robot_PutQR(i) 
                    elif abs(x1 - center_x) < 30 and  abs( y2 - feature[1]) < 30:
                        for i in range(1,5):
                            if i == self.QR_value:
                                self.master.robot.robot_getQR(4)
                                self.master.robot.robot_PutQR(i) 
                    
                    # 绘出图像上条形码的数据和条形码类型
                    text = "{} ({})".format(barcodeData, barcodeType)
                    cv2.putText(self.frame, text, (x, y - 10), cv2.FONT_HERSHEY_SIMPLEX,.5, (0, 0, 125), 2) 

        except Exception as e:
            logger.error(e,exc_info=True)

    def release_camera(self):  
        if self.cap.isOpened():  
            self.cap.release()  

    #### 展示图片
    def display(self,):
        try:
            #### 原图缩放
            img = cv2.resize(self.frame,(1020,520))
            rgb_img = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
           
            ####将rgb格式转换为qt可以识别的格式
            img_dis = QImage(rgb_img,rgb_img.shape[1],rgb_img.shape[0],QImage.Format_RGB888)
            ####加载图片，并设定图片大小
            img_dis = QPixmap(img_dis)
            ####显示图片--- 将图片放到label中心
            self.label.setAlignment(QtCore.Qt.AlignCenter) 
            self.label.setPixmap(img_dis)
            time.sleep(0.001)
        except Exception as e:
            logger.error(e,exc_info=True)

    def run(self): 
        self.cap = cv2.VideoCapture(camera_nun, cv2.CAP_V4L)
        self.cap.set(cv2.CAP_PROP_FOURCC,cv2.VideoWriter_fourcc('M','J','P','G'))
        self.cap.set(cv2.CAP_PROP_FPS, 30)

        while not self.Is_exit:
            while not self.stop:
                try:
                    ret, self.frame = self.cap.read()
                    if not ret:
                        self.gui_signal.emit(json.dumps({"source":2,}))
                        time.sleep(0.05)
                        self.cap = cv2.VideoCapture(camera_nun, cv2.CAP_V4L)
                        self.cap.set(cv2.CAP_PROP_FOURCC,cv2.VideoWriter_fourcc('M','J','P','G'))
                        self.cap.set(cv2.CAP_PROP_FPS, 30)
                    
                    if ret:

                        img = cv2.resize(self.frame, (1020,520), interpolation=cv2.INTER_LINEAR)

                        #### 进行颜色检测识别--垃圾分拣
                        if self.program_flag ==0:
                            pass
                            # self.color_recong(image)
                        
                        #### 进行轮廓检测识别
                        elif self.program_flag == 1:
                            pass
                            # self.contour_recong(image)  
                        
                        #### 进行二维码识别
                        elif self.program_flag == 2:
                            self.master.robot_action = 2
                            self.QR_test(img)
                            
                            self.program_flag = 6
                            self.master.robot_action = 0   
                        
                        #### 进行OCR检测识别
                        elif self.program_flag == 3:
                            pass
                            # self.ocr_test(image) 
                        
                        elif self.program_flag == 4:
                            pass

                        self.display()
                    time.sleep(0.1)        
                except Exception as e:
                    logger.error(e,exc_info=True)

    def cap_camera(self,msg):
        message_json = json.loads(msg)
        camera_num = int(message_json.get("camera_num"))
        if camera_num == 0 or camera_num ==1 or camera_num ==2 or camera_num ==9:
            self.cap = cv2.VideoCapture(camera_num)
            ret, self.frame = self.cap.read()
            if ret :
                self.stop = 0
                self.gui_signal.emit(json.dumps({"source":0,"camera_num":camera_num}))
            else:
                self.gui_signal.emit(json.dumps({"source":3,"camera_num":camera_num}))
        else:
            #### 返回主线程：摄像头编号是0，1，2，3
            self.gui_signal.emit(json.dumps({"source":1}))
    
